import math
import copy
import numpy as np

# 归一化
def normalization(data, indices, isZeroToOneConfig):
  data = np.array(data)
  copy_data = copy.deepcopy(data)
  min_max_list = []
  
  # 寻找每个特征的最大最小值
  # 这种找min max的方式有bug。例如我现在有一个很大的值99，此时99 < 100，所以min_max列表换成了【99， -100】，然后随着后续的添加，99可能被替换掉了，但同时99也不会存在在max的位置。
  # for i in range(len(indices)):
  #   min_max_list.append([100, -100])
  #   for vehicle_data in copy_data:
  #     for row in vehicle_data:
  #       # min、max
  #       if (row[indices[i]] < min_max_list[i][0]):
  #         min_max_list[i][0] = row[indices[i]]
  #       elif (row[indices[i]] > min_max_list[i][1]):
  #         min_max_list[i][1] = row[indices[i]]
  for i in range(len(indices)):
    min_max_list.append([100, -100])
    for vehicle_data in copy_data:
      for row in vehicle_data:
        # min、max
        if (row[indices[i]] < min_max_list[i][0]):
          min_max_list[i][0] = row[indices[i]]
        # 在这里做修改
        if (row[indices[i]] > min_max_list[i][1]):
          min_max_list[i][1] = row[indices[i]]

  # 处理最大最小值相等的情况
  for i in range(len(min_max_list)):
    if (min_max_list[i][0] == min_max_list[i][1]):
      min_max_list[i][1] = min_max_list[i][0] + 1 # 防止除0错误

  # 归一化
  for vehicle_data in copy_data:
    for row in vehicle_data:
      for i in range(len(indices)):
        # 归一化
        if (isZeroToOneConfig[i] == True):
          row[indices[i]] = (row[indices[i]] - min_max_list[i][0]) / (min_max_list[i][1] - min_max_list[i][0]) # 【0，1】区间
        else:
          row[indices[i]] = 2 * (row[indices[i]] - min_max_list[i][0]) / (min_max_list[i][1] - min_max_list[i][0]) - 1 # 【-1，1】区间

  return copy_data, min_max_list

# 反归一化
def anit_normalization(data, indices, min_max_list, isZeroToOneConfig):
  data = np.array(data)
  copy_data = copy.deepcopy(data)

  for vehicle_data in copy_data:
    for row in vehicle_data:
      for i in range(len(indices)):
        # 反归一化
        if (isZeroToOneConfig[i] == True):
          row[indices[i]] = row[indices[i]] * (min_max_list[i][1] - min_max_list[i][0]) + min_max_list[i][0]
        else:
          row[indices[i]] = (row[indices[i]] + 1) * (min_max_list[i][1] - min_max_list[i][0]) / 2 + min_max_list[i][0]

  return copy_data

# 创建lstm数据集
def create_lstm_dataset(data, n_past, n_future, past_feature_indices=[4, 5], future_feature_indices=[5]):
  data = np.array(data)
  X, Y = [], []
  for vehicle_data in data:
    for i in range(len(vehicle_data) - n_past - n_future + 1):
      X.append(vehicle_data[i : i + n_past, past_feature_indices])
      Y.append(vehicle_data[i + n_past : i + n_past + n_future, future_feature_indices])
  X, Y = np.array(X), np.array(Y)
  return X, Y